﻿#include<ctime>
#include<sstream>
#include<iostream>
#include"Date.h"

using namespace std;

int Date::dmax[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int Date::days_of_month(int y, int m) {
	return dmax[m - 1] + (is_leap(y) && m == 2);
}

Date::Date() {
	time_t current = time(NULL);
	struct tm local;
	localtime_s(&local, &current);

	y = local.tm_year + 1900;
	m = local.tm_mon + 1;
	d = days_of_month(y, m);
}

Date Date::preceding_day() const {
	Date preceding = *this;
	if (preceding.d == 0) {
		if (preceding.m == 0) {
			preceding.m = 12;
			preceding.y--;
		}
		else {
			preceding.m--;
		}
		preceding.d = days_of_month(preceding.y, preceding.m);
	}
	else {
		preceding.d--;
	}
	return preceding;
}

Date Date::following_day() const {
	Date f = *this;
	if (d == days_of_month(y, m)) {
		f.d = 1;
		if (m == 12) {
			f.y++;
			f.m = 1;
		}
		else {
			f.m++;
		}
	}
	else {
		f.d++;
	}
	return f;
}

int Date::day_of_year() const {
	int days = 0;
	for (int i = 0; i < m - 1; i++) {
		days += dmax[i];
	}
	return days + d;
}

int Date::day_of_week() const {
	int yy = y;
	int mm = m;
	if (mm == 1 || mm == 2) {
		yy--;
		mm += 12;
	}
	return (yy + yy / 4 - yy / 100 + yy / 400 + (13 * mm + 8) / 5 + d) % 7;
}

string Date::to_string() const {
	ostringstream s;
	s << y << "年" << m << "月" << d << "日";
	return s.str();
}

std::ostream& operator<<(std::ostream& s, const Date& x) {
	return s << x.to_string();
}